package com.ruoyi.fire.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.fire.domain.DGatewayMessage;
import com.ruoyi.fire.domain.DWaterDeviceMessage;
import com.ruoyi.fire.domain.DWaterMessage;
import com.ruoyi.fire.domain.dto.UplinkDataDTO;
import com.ruoyi.fire.mapper.DWaterMessageMapper;
import com.ruoyi.fire.service.IDWaterDeviceMessageService;
import com.ruoyi.fire.service.IDWaterMessageService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @PackageName: com.iot.fire.service.impl
 * @ClassName: DWaterMessageServiceImpl
 * @Description:
 * @Author: czl
 * @Date: 2025/11/10 23:17
 */
@Service
@RequiredArgsConstructor
public class DWaterMessageServiceImpl extends ServiceImpl<DWaterMessageMapper, DWaterMessage> implements IDWaterMessageService {

    private final IDWaterDeviceMessageService waterDeviceMessageService;

    /**
     * 根据设备编号查询列表
     *
     * @param deviceNo 设备编码
     * @return
     */
    @Override
    public DWaterMessage selectLastOneByDeviceNo(String deviceNo) {
        LambdaQueryWrapper<DWaterMessage> wrapper = Wrappers.lambdaQuery(DWaterMessage.class);
        wrapper.eq(DWaterMessage::getSN, deviceNo);
        // 添加时间条件：查询六个半小时内的数据
        Date condionDate = Date.from(LocalDateTime.now().minusHours(6).minusMinutes(30).atZone(ZoneOffset.systemDefault()).toInstant());
        wrapper.gt(DWaterMessage::getTime, condionDate);
        wrapper.last("limit 1");
        DWaterMessage waterMessage = getOne(wrapper);
        if (waterMessage != null) {
            waterMessage.setWaterDeviceMessages(waterDeviceMessageService.selectByDeviceId(waterMessage.getId()));
        }
        return waterMessage;
    }

    /**
     * 根据设备编号查询最近7小时列表
     * @param deviceNo 设备编码
     * @return
     */
    @Override
    public DWaterMessage selectLast7HostOneByDeviceNo(String deviceNo) {
        LambdaQueryWrapper<DWaterMessage> wrapper = Wrappers.lambdaQuery(DWaterMessage.class);
        wrapper.eq(DWaterMessage::getSN, deviceNo);

        // 添加时间条件：查询七小时内内的数据
        Date conditionDate = Date.from(LocalDateTime.now().minusHours(7).atZone(ZoneOffset.systemDefault()).toInstant());
        wrapper.gt(DWaterMessage::getTime, conditionDate);

        // 按时间倒序排列
        wrapper.orderByDesc(DWaterMessage::getTime);
        // 只取最新的一条记录
        wrapper.last("limit 1");
        return getOne( wrapper);
    }

    /**
     * 根据设备编号查询列表
     *
     * @param waterDeviceNos 设备编码
     * @return
     */
    @Override
    public List<DWaterMessage> selectLastOneByDeviceNos(Set<String> waterDeviceNos) {
        LambdaQueryWrapper<DWaterMessage> wrapper = Wrappers.lambdaQuery(DWaterMessage.class);
        wrapper.in(DWaterMessage::getSN, waterDeviceNos);
        wrapper.last("GROUP BY SN ORDER BY TIME DESC");
        List<DWaterMessage> list = list(wrapper);
        if (!CollectionUtils.isEmpty(list)) {
            for (DWaterMessage waterMessage : list) {
                waterMessage.setWaterDeviceMessages(waterDeviceMessageService.selectByDeviceId(waterMessage.getId()));
            }
        }
        return list;
    }

    /**
     * 设备上行数据
     *
     * @param uplinkDataDTO
     * @return
     */
    @Override
    public Page<DWaterMessage> uplinkData(UplinkDataDTO uplinkDataDTO) {
        LambdaQueryWrapper<DWaterMessage> wrapper = Wrappers.lambdaQuery(DWaterMessage.class);
        wrapper.eq(StringUtils.isNotEmpty(uplinkDataDTO.getDeviceNo()), DWaterMessage::getSN, uplinkDataDTO.getDeviceNo());
        wrapper.orderByDesc(DWaterMessage::getTime);
        Page<DWaterMessage> page = page(uplinkDataDTO.build(), wrapper);
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            for (DWaterMessage record : page.getRecords()) {
                record.setWaterDeviceMessages(waterDeviceMessageService.selectByDeviceId(record.getId()));
            }
        }
        return page;
    }

    /**
     * 设备在线状态
     * @param deviceNo
     * @return
     */
    @Override
    public boolean OnlineStatus(String deviceNo) {
        LambdaQueryWrapper<DWaterMessage> wrapper = Wrappers.lambdaQuery(DWaterMessage.class);
        wrapper.eq(DWaterMessage::getSN, deviceNo).orderByDesc(DWaterMessage::getTime);
        wrapper.last("limit 1");
        DWaterMessage waterMessage = getOne(wrapper);

        // 如果没有找到消息记录，则认为不在线
        if (waterMessage == null) {
            return false;
        }

        // 判断最后上报时间是否超过7小时
        long timeDifferenceMillis = System.currentTimeMillis() - waterMessage.getTime().getTime();
        // 7小时转换为毫秒
        long sevenHoursInMillis = 7 * 60 * 60 * 1000L;

        if (timeDifferenceMillis > sevenHoursInMillis) {
            // 超过7小时未上报，判定为离线
            return false;
        } else {
            // 在线
            return true;
        }
    }
}
